home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / fingserv.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  6KB  |  277 lines

  1.  
  2. /*
  3.  *
  4.  *    Finger support...
  5.  *
  6.  *    Finger server routines.  Written by Michael T. Horne - KA7AXD.
  7.  *    Copyright 1988 by Michael T. Horne, All Rights Reserved.
  8.  *    Permission granted for non-commercial use and copying, provided
  9.  *    that this notice is retained.
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include "global.h"
  15. #include "config.h"
  16. #include "mbuf.h"
  17. #include "timer.h"
  18. #include "internet.h"
  19. #include "icmp.h"
  20. #include "netuser.h"
  21. #include "tcp.h"
  22. #include "ftp.h"
  23. #include "telnet.h"
  24. #include "iface.h"
  25. #include "ax25.h"
  26. #include "lapb.h"
  27. #include "finger.h"
  28. #include "session.h"
  29. #include "nr4.h"
  30. #ifdef    UNIX
  31. #include <string.h>
  32. #endif
  33.  
  34. #if (defined(BSD) || defined(SUNOS4))
  35. char *sprintf();
  36. #endif
  37.  
  38. struct tcb *fing_tcb = NULLTCB;
  39. int16 finger_notify = 1;
  40.  
  41. finger1(argc, argv)
  42. int    argc;
  43. char    *argv[];
  44. {
  45.     extern int32    ip_addr;
  46.     struct socket    lsocket;
  47.     void        fing_state();
  48.     void        rcv_fing();
  49.  
  50.     if (fing_tcb)
  51.         return;
  52.     /* start finger daemon */
  53.     lsocket.address = ip_addr;
  54.     if(argc < 2)
  55.         lsocket.port = FINGER_PORT;
  56.     else
  57.         lsocket.port = atoi(argv[1]);
  58.     fing_tcb = open_tcp(&lsocket, NULLSOCK, TCP_SERVER, 0, rcv_fing,
  59.         NULLVFP, fing_state, 0, (char *)NULL);
  60.     return;
  61. }
  62. /*
  63.  *    Handle incoming finger connections and closures.
  64.  * 
  65.  */
  66. /*ARGSUSED*/
  67. void
  68. fing_state(tcb,old,new)
  69. struct tcb    *tcb;
  70. char        old,        /* old state */
  71.         new;        /* new state */
  72. {
  73.     struct finger    *fing;
  74.     void        snd_fing();
  75.  
  76.     switch(new){
  77.     case ESTABLISHED:
  78.         log(tcb,"open Finger");
  79.         fing = (struct finger *) malloc(sizeof(struct finger));
  80.  
  81.         tcb->user = (char *)fing;    /* Upward pointer */
  82.         fing->tcb = tcb;        /* Downward pointer */
  83.         if (finger_notify)  {
  84.             printf("\007You're being fingered by %s!\n",
  85.                  psocket(&tcb->conn.remote));
  86.             fflush(stdout);
  87.         }
  88.         return;
  89.     case CLOSED:
  90.         if (tcb == fing_tcb)
  91.             fing_tcb = NULLTCB;
  92.         if (tcb->user != NULLCHAR)
  93.             free(tcb->user);
  94.         del_tcp(tcb);
  95.         break;
  96.     }
  97. }
  98.  
  99. /*
  100.  *    Stop the finger server.
  101.  */
  102.  
  103. finger0()
  104. {
  105.     if (fing_tcb != NULLTCB) {
  106.         close_tcp(fing_tcb);
  107.         fing_tcb = NULLTCB;
  108.     }
  109.     return;
  110. }
  111.  
  112. /*
  113.  *    Send a short message on a tcb
  114.  */
  115.  
  116. static
  117. sndmsg(tcb, msg)
  118. struct tcb    *tcb;        /* tcb to send on */
  119. char        *msg;        /* message to send */
  120. {
  121.     struct mbuf *bp;
  122.  
  123.     bp = qdata(msg,(int16)strlen(msg));
  124.     send_tcp(tcb,bp);
  125. }
  126.  
  127. /*
  128.  *    Finger receive upcall.  This is the guts of the finger server.
  129.  *    The user to finger is read from the socket.  If only a newline
  130.  *    is read, then send the remote host a list of all known 'users' on
  131.  *    this system.
  132.  */
  133.  
  134. /*ARGSUSED*/
  135. void
  136. rcv_fing(tcb, ccnt)
  137. register struct tcb    *tcb;
  138. int16            ccnt;
  139. {
  140.     FILE        *fuser;
  141.     struct mbuf    *mbuf,
  142.             *bp;
  143.     char        *buf,
  144.             *who,
  145.             *finger_file,
  146.             *path,
  147.             ch,
  148.             temp[80],
  149.             user[80];
  150.     int        cnt;
  151.     int        size;
  152.  
  153.  
  154.     if ((struct finger *) tcb->user == NULLFING)    /* uh oh! */
  155.         return;
  156.     if(recv_tcp(tcb,&bp,FINGNAMELEN) == 0)
  157.         return;
  158.     if ((who = malloc(FINGNAMELEN + 1)) == NULL) {
  159.         free_p(bp);
  160.         return;
  161.     }
  162.  
  163.     cnt = pullup(&bp, who, FINGNAMELEN);    /* get 'user' name */
  164.     who[cnt] = '\0';            /* NULL terminate it */
  165.     free_p(bp);                /* all done with bp */
  166.  
  167.     if (*who == '\015' || *who == '\012') {    /* give him a user listing */
  168.         int found = 0;
  169.  
  170.         path = (char *) malloc((unsigned)(strlen(fingerpath)
  171.             + strlen(fingersuf) + 2));
  172.         /* create wildcard path to finger files */
  173.         strcpy(path, fingerpath);
  174.         strcat(path, "*");
  175.         strcat(path, fingersuf);
  176.  
  177.         sndmsg(tcb, "Known users on this system:\015\012");
  178.         for (filedir(path, 0, user); user[0] != '\0';
  179.             filedir (path, 1, user))  {
  180.             found++;
  181.             *index(user, '.') = '\0';
  182.             sprintf(temp, "        %s\015\012", user);
  183.             sndmsg(tcb, temp);
  184.         }
  185.         if (!found)
  186.             sndmsg(tcb, "None!\015\012");
  187.  
  188.         free(path);
  189.     }
  190.     else {
  191.         buf = who;
  192.         while (*buf != '\015' && *buf != '\012' && *buf != '\0')
  193.             buf++;
  194.         *buf = '\0';
  195.         /*
  196.          *    Create path to user's finger file and see if the
  197.          *    the file exists.
  198.          */
  199.         finger_file = malloc((unsigned)(strlen(fingerpath) + strlen(who)
  200.                 + strlen(fingersuf) + 1));
  201.         if (finger_file == NULLCHAR) {    /* uh oh... */
  202.             free(who);        /* clean up */
  203.             close_tcp(tcb);        /* close socket */
  204.             return;
  205.         }
  206.         strcpy(finger_file, fingerpath);
  207.         strcat(finger_file, who);
  208.         strcat(finger_file, fingersuf);
  209.  
  210.         if ((fuser = fopen(finger_file, "r")) == (FILE *) NULL) {
  211.             sprintf(temp, "User %s unknown on this system\015\012",
  212.                 who);
  213.             sndmsg(tcb, temp);
  214.         }
  215.         else {                /* valid 'user' */
  216.             char    nl = '\0';    /* newline flag */
  217.  
  218.             /*
  219.              * Here's a tricky routine to make sure we get
  220.              * everything in, including "\r\n".  It's needed since
  221.              * UNIX files have only a '\n' for EOL.  What is
  222.              * REALLY NEEDED is a standardized routine for filling
  223.              * mbufs from file input so that each server doesn't
  224.              * have to do it themselves!  Ditto for emptying
  225.              * mbufs!  The problem of "\r\n" doesn't rear its
  226.              * ugly head with MessyDOS, but with UNIX boxes...
  227.              */
  228.  
  229.             ch = fgetc(fuser);    /* first get must be outside */
  230.             while (!feof(fuser)) {
  231.                 size = tcb->window;
  232.                 if ((mbuf = alloc_mbuf((int16)size)) == NULLBUF) {
  233.                     fclose(fuser);    /* barf */
  234.                     free(who);
  235.                     free(finger_file);
  236.                     return;
  237.                 }
  238.                 buf = mbuf->data;    /* pointer to buffer */
  239.                 while(!feof(fuser) && size--) {    /* loop */
  240.                     if (nl) {
  241.                         *buf++ = '\012';/* line feed */
  242.                         mbuf->cnt++;
  243.                         nl--;
  244.                     }
  245.                     else switch(ch) {
  246.                         case '\032':    /* NO ^Z's! */
  247.                             break;
  248. #ifndef    UNIX
  249.                         case '\012':    /* ignore LF */
  250.                             break;
  251. #else
  252.                         case '\012':    /* change LF */
  253.                             ch = '\015'; /* to CR */
  254.                                 /* fall thru */
  255. #endif
  256.                         case '\015':    /* EOL */
  257.                             nl++;    /* fall thru */
  258.                         default:
  259.                             *buf++ = ch;
  260.                             mbuf->cnt++;
  261.                             break;
  262.                     }
  263.                     if (!nl)
  264.                         ch = fgetc(fuser);
  265.                 }
  266.                 send_tcp(tcb, mbuf);    /* send info */
  267.             }
  268.             fclose(fuser);
  269.         }
  270.         free(finger_file);
  271.     }
  272.     free(who);
  273.     close_tcp(tcb);            /* close socket */
  274.     return;
  275. }
  276.  
  277.